/**
 * Axios功能封装
 */

// 请求锁
let safeRequestLock = []
// 请求结果
let safeRequestPromise = {}

// region 创建axios实例
// @ts-ignore
let axios = $GP.Server.axios;
let axiosObject = axios.create({
    timeout: 3000,
    // 请求头
    headers: {
        'X-Requested-With': 'XMLHttpRequest',
        'Accept': 'application/json',
        'Content-Type': 'application/json',
    },
    cancelRequest: false, // 取消请求
    loginAuth: false, // 登陆认证
    loadingEnable: false, // 启用加载
    loadingMessage: '', // 加载提示
    loadingForbidClick: true, // 加载时禁止点击
})
// 请求取消控制
/*
if ('AbortController' in window) {
    // @ts-ignore
    let cancelController = new window.AbortController()
    axiosObject.signal = cancelController.signal // 取消信号
    axiosObject.interceptors.request.use(async (config) => {
        if (config.cancelRequest) {
            console.log('基于AbortController取消请求', cancelController,  cancelController.abort())
            cancelController.abort()
        }
        return config
    }, (error) => {
        console.log('[service内部]#请求拦截出错', error)
    })
} else {
    // 通过token取消兼容代码
    // @ts-ignore
    let cancelSource = axios.CancelToken.source()
    axiosObject.cancelToken = cancelSource.token // 取消token[兼容代码]
    axiosObject.interceptors.request.use(async (config) => {
        if (config.cancelRequest) {
            console.log('基于CancelToken取消请求')
            cancelSource.cancel('请求取消')
        }
        return config
    }, (error) => {
        console.log('[service内部]#请求拦截出错', error)
    })
}
*/
// endregion

// 请求拦截
axiosObject.interceptors.request.use(async (config) => {
    if (config.cancelRequest) {
        throw new Error('取消请求')
    }
    return config
}, (error) => {
    console.log('[service内部]#请求拦截出错', error)
})
// region 响应拦截器
axiosObject.interceptors.response.use(async (response) => {
    console.log('[service内部]#响应拦截器', response)
    return response
})
// endregion

let getAxiosFunc = () => {
    return axiosObject
}

/**
 * 安全请求
 * @param setting
 */
let safeRequestFunc = async (setting: object = {}): Promise<object> => {
    try {
        let safeKey = setting.id || setting.url
        if (!safeRequestPromise.hasOwnProperty(safeKey)) {
            console.log('[safeRequestFunc]#未在请求队列', safeKey)
            safeRequestPromise[safeKey] = []
        }
        return new Promise(async (resolve, reject) => {
            // 推入队列
            safeRequestPromise[safeKey].push({
                resolve,
                reject
            })
            if (safeRequestLock.indexOf(safeKey) === -1) {
                console.log('[safeRequestFunc]#请求加锁', safeKey, setting)
                // 加锁
                safeRequestLock.push(safeKey)
                let [apiError, apiResult] = await requestFunc(setting)
                console.log('[safeRequestFunc]#请求结果', apiError, apiResult)
                // 批量处理
                if (safeRequestPromise[safeKey].length) {
                    while (safeRequestPromise[safeKey].length) {
                        safeRequestPromise[safeKey].shift().resolve([apiError, apiResult])
                    }
                }
                // 解锁
                let lockIndex = safeRequestLock.indexOf(safeKey)
                if (lockIndex !== -1) {
                    safeRequestLock.splice(lockIndex, 1)
                }
            }
        })
    } catch (exception) {
        console.log('[safeRequestFunc]#异常', exception.message)
        return Promise.resolve([exception.message || '[safeRequestFunc]#异常', null])
    }
}

/**
 * 请求方法
 * @param setting
 */
let requestFunc = async (setting: object = {}): Promise<object> => {
    try {
        console.log('[requestFunc]#发起请求', setting)
        let [apiError, apiResult] = await axiosObject.request(setting).then((response) => {
            console.log('[requestFunc]#请求响应', response)
            if (response.status == 200) {
                let apiData = response.data
                if (response.data.code !== 1) {
                    if (response.data.data && apiData.data.event) {
                        // 发布事件
                        // @ts-ignore
                        window.EMA.fire(apiData.data.event)
                    }
                }
                return [null, response.data]
            }
            return [response.statusText, null]
        }).catch((exception) => {
            console.log('[axiosObject.request]#异常', exception.message)
            return [exception.message, null]
        })
        console.log('[requestFunc]#请求结果', apiError, apiResult)
        return Promise.resolve([apiError, apiResult])
    } catch (exception) {
        console.log('[requestFunc]#异常', exception.message)
        return Promise.resolve([exception.message || '[requestFunc]#异常', null])
    }
}

export {
    getAxiosFunc,
    safeRequestFunc,
    requestFunc,
}
